#!/usr/bin/env python
"""
应用健康检查脚本 - 用于验证Django应用服务是否正常运行
"""

import os
import sys
import time
import socket
import requests
import django
from pathlib import Path

# 添加项目根目录到Python路径
BASE_DIR = Path(__file__).resolve().parent.parent
sys.path.append(str(BASE_DIR))

# 设置Django环境
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'boxuser.settings')
django.setup()

# 导入Django设置
from django.conf import settings
from django.db import connection

def check_database_connection():
    """检查数据库连接是否正常"""
    try:
        with connection.cursor() as cursor:
            cursor.execute("SELECT 1")
            result = cursor.fetchone()
            return result[0] == 1
    except Exception as e:
        print(f"数据库连接失败: {e}")
        return False

def check_migrations():
    """检查是否有未应用的迁移"""
    from django.db.migrations.executor import MigrationExecutor
    executor = MigrationExecutor(connection)
    plan = executor.migration_plan(executor.loader.graph.leaf_nodes())
    return len(plan) == 0

def check_application_health(url=None):
    """检查应用是否响应HTTP请求"""
    if url is None:
        host = socket.gethostbyname(socket.gethostname())
        port = getattr(settings, 'PORT', 8000)
        url = f"http://{host}:{port}/"
    
    try:
        response = requests.get(url, timeout=5)
        if response.status_code == 200:
            return True, response.status_code
        else:
            return False, response.status_code
    except requests.RequestException as e:
        return False, str(e)

def check_static_files():
    """检查静态文件是否存在"""
    static_root = settings.STATIC_ROOT
    if not os.path.exists(static_root):
        print(f"静态文件目录不存在: {static_root}")
        return False
    
    # 检查是否有文件
    if not any(os.scandir(static_root)):
        print(f"静态文件目录为空: {static_root}")
        return False
    
    return True

def check_media_dir():
    """检查媒体文件目录是否存在并可写"""
    media_root = settings.MEDIA_ROOT
    if not os.path.exists(media_root):
        try:
            os.makedirs(media_root, exist_ok=True)
            print(f"已创建媒体目录: {media_root}")
        except Exception as e:
            print(f"无法创建媒体目录: {e}")
            return False
    
    # 检查是否可写
    test_file = os.path.join(media_root, '.test_write')
    try:
        with open(test_file, 'w') as f:
            f.write('test')
        os.remove(test_file)
        return True
    except Exception as e:
        print(f"媒体目录不可写: {e}")
        return False

def run_full_health_check(url=None):
    """运行完整的健康检查"""
    print("开始执行系统健康检查...\n")
    
    # 检查数据库
    print("检查数据库连接...", end="")
    db_ok = check_database_connection()
    print(" 通过" if db_ok else " 失败")
    
    # 检查迁移
    if db_ok:
        print("检查数据库迁移...", end="")
        migrations_ok = check_migrations()
        print(" 通过" if migrations_ok else " 失败 (有未应用的迁移)")
    else:
        migrations_ok = False
    
    # 检查静态文件
    print("检查静态文件...", end="")
    static_ok = check_static_files()
    print(" 通过" if static_ok else " 失败")
    
    # 检查媒体目录
    print("检查媒体目录...", end="")
    media_ok = check_media_dir()
    print(" 通过" if media_ok else " 失败")
    
    # 检查应用健康
    print("检查应用HTTP响应...", end="")
    app_ok, status = check_application_health(url)
    print(f" 通过 (状态码: {status})" if app_ok else f" 失败 ({status})")
    
    # 总结
    all_ok = db_ok and migrations_ok and static_ok and media_ok and app_ok
    print("\n健康检查汇总:")
    print(f"- 数据库连接: {'✓' if db_ok else '✗'}")
    print(f"- 数据库迁移: {'✓' if migrations_ok else '✗'}")
    print(f"- 静态文件: {'✓' if static_ok else '✗'}")
    print(f"- 媒体目录: {'✓' if media_ok else '✗'}")
    print(f"- 应用HTTP响应: {'✓' if app_ok else '✗'}")
    print(f"\n总体状态: {'健康' if all_ok else '不健康'}")
    
    return all_ok

if __name__ == "__main__":
    url = sys.argv[1] if len(sys.argv) > 1 else None
    success = run_full_health_check(url)
    sys.exit(0 if success else 1) 